<?php
/*------------------------------------------------------------------------------
this file is part of Web Application Kit http://webappkit.net
Copyright (C) 2006 J.Ducastel <jducastel@jducastel.fr>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
------------------------------------------------------------------------------*/

/**
* webappkit library management core service
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
class wakLib extends wakService {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access public
	*/
	function wakLib() {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access public
	*/
	function __construct() {
		parent::__construct();
		// referencing debug service instance
		$this->deb=&wak::getservice('wakdebug');
		// including required libraries
		$this->_includeLibFile(WAK_CORE_PATH.'lib/pathnodes/pathnode.class.php');
		$this->_includeLibFile(WAK_CORE_PATH.'lib/pathnodes/foldernode.pathnode.class.php');
		$this->_includeLibFile(WAK_CORE_PATH.'lib/pathnodes/phplibfolder.foldernode.class.php');
		$this->_includeLibFile(WAK_CORE_PATH.'lib/pathnodes/filenode.pathnode.class.php');
		$this->_includeLibFile(WAK_CORE_PATH.'lib/pathnodes/textfilenode.filenode.class.php');
		$this->_includeLibFile(WAK_CORE_PATH.'lib/pathnodes/phplibfile.textfilenode.class.php');
		$this->_includeLibFile(WAK_CORE_PATH.'lib/pathnodes/filenode.pathnode.class.php');
		$this->_includeLibFile(WAK_CORE_PATH.'lib/pathnodes/yamlfilenode.filenode.class.php');
		$this->_includeLibFile(WAK_CORE_PATH.'lib/spyc-0.2.3/spyc.php');
		$this->_includeLibFile(WAK_CORE_PATH.'lib/datapath.class.php');
		// creating core and app folder instances
		$this->coreNode=new phplibfolder(WAK_CORE_PATH.'lib');
		$this->appNode=new phplibfolder('app/lib');
		// loading library indexes
		//echo wakapi::vardump($this->coreNode);
	}/**/
	/**
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* Includes class definition file, either from /lib or WAK_CORE_PATH/lib
	* Includes also parent class def files and dependances.
	* @param string $class
	* @param bool $fromCore default false
	* @access public
	* @return bool
	*/
	function needClass($class, $fromCore=false) {
		//echo "<p>$class</p>";
		// is class already defined ?
		if (class_exists($class)) return true;
		// searching for class definition
		if ($this->_defineClass($class,$fromCore)) {
			//echo $this->deb->vardump($this);
			//echo "<p>defined $class</p>";
			return true;
		}
		//$this->deb->warning("couldn't find class $class");
		trigger_error("couldn't find class $class");
		//throw Exception("couldn't find class $class");
		return false;
	}/**/
	
	/**
	* return stats for loaded files
	* @param
	* @access public
	* @return array
	*/
	function stats() {
		return array(
			'files'=>$this->filesCount
			, 'weight'=>$this->filesWeight
			, 'classes'=>$this->definedClasses
		);
	}/**/
	
	/**
	* 
	* @param
	* @access public
	* @return 
	* /
	function () {
		
	}/**/
	
	/**
	* 
	* @param
	* @access public
	* @return 
	* /
	function () {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @private int included files count
	*/
	var $filesCount=0;
	/**
	* @private total included weight count
	*/
	var $filesWeight=0;
	/**
	* @private array included/defined classes
	*/
	var $definedClasses=array();
	/**
	* @private array configuration file
	*/
	var $cfg=array(
		'coreClasses'=>array()
		,'appClasses'=>array()
		, 'filesClassDependancies'=>array()
	);
	/**
	* @private phplibfolder core folder node
	*/
	var $coreNode;
	/**
	* @private phplibfolder app folder node
	*/
	var $appNode;
/*------------------------------------------------------------------------------
                                                                 private methods
------------------------------------------------------------------------------*/
	/**
	* searches for class definition file, includes it with dependancies
	* @access private
	* @param string $class
	* @param bool $fromCore
	* @return bool
	*/
	function _defineClass($class,$fromCore=false) {
		// searching app-level
		if (!$fromCore and $file=$this->appNode->locateClassDef($class)) {
			return $this->_defineClassFromNode($class,$this->appNode);
		}
		// searching core-level
		if ($file=$this->coreNode->locateClassDef($class)) {
			return $this->_defineClassFromNode($class,$this->coreNode);
		}
		// failed
		return false;
	}/**/
	
	/**
	* include class definition from folderNode
	*/
	function _defineClassFromNode($class,&$node) {
		// getting dependancies
		if ($required_classes=$node->getClassRequiredClasses($class))
			foreach ($required_classes as $required)
				$this->needClass($required);
		// including file
		//echo $class;
		return $node->defineClass($class);
	}
	
	/**
	* includes a library file, take care of dependancies
	* @access private
	* @arg string $file full file's path
	* @return bool
	*/
	function _includeLibFile($file) {
		// searching for dependancies
		// class dependancies
		/*if (isset($this->cfg['filesClassDependancies'][$file])) {
			$classes=explode(' ',trim($this->cfg['filesClassDependancies'][$file]));
			// echo $this->deb->vardump($classes);
			foreach ($classes as $class)
				$this->needClass($class);
		}*/
		// storing stats
		if (!file_exists($file)) 
			return false;
		$this->filesCount++;
		$this->filesWeight+=filesize($file);
		return include_once($file);
	}/**/
}
?>
